package nu.zoom.swing.desktop.component.stringmenu;

import java.io.Serializable;

/**
 * Holds information about a menu item. A menu item is a presentation name,
 * which is shown on the menu, and a value. When a menu is selected the value is
 * used in callbacks to indicate which menu was selected.
 * 
 * @param <T>
 *            The value type. Must be comparable since it is used when comparing
 *            the menu items and serializable since it is stored in the
 *            Preferences to persist menus.
 */
@SuppressWarnings("serial")
public class StringMenuItem<T extends Comparable<T> & Serializable> implements
		Comparable<T>, Serializable {
	private T value;

	private String presentationName;

	/**
	 * Create a new menu item.
	 * 
	 * @param value
	 *            The value of the menu, may not be null.
	 * @param presentationName
	 *            The string that is shown on the menu. If null the default is
	 *            to take toString on the value and truncating if too long.
	 */
	public StringMenuItem(T value, String presentationName) {
		if (value == null) {
			throw new IllegalArgumentException("Value may not be null");
		}

		this.value = value;
		this.presentationName = presentationName;

		if ((presentationName == null)
				|| (presentationName.trim().length() < 1)) {
			this.presentationName = value.toString();
			if (this.presentationName.length() > 20) {
				this.presentationName = this.presentationName
						.substring(this.presentationName.length() - 20);
			}
		}
	}

	/**
	 * @return the presentationName
	 */
	public String getPresentationName() {
		return presentationName;
	}

	/**
	 * @return the value
	 */
	public T getValue() {
		return value;
	}

	/**
	 * Two menu items are considered the same if their values are equal. This
	 * comparison ignores the presentationName.
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof StringMenuItem<?>) {
			return value.equals(((StringMenuItem<?>) obj).value);
		} else {
			return false;
		}
	}

	@Override
	public int hashCode() {
		return value.hashCode();
	}

	@Override
	public String toString() {
		return presentationName;
	}

	/**
	 * Compares this menu item to another by delegating to this items value for
	 * comparison.
	 * 
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	public int compareTo(T o) {
		return value.compareTo(o);
	}
}
